<?php

namespace app\health\service;

use Exception;
use think\Log;

/**
 * 微信小程序接口服务
 * @method \WeMini\Crypt WeMiniCrypt() static 小程序数据加密处理
 */
class WeMiniService
{

    /**
     * 静态初始化对象
     * @param string $name
     * @param array $arguments
     * @return mixed
     * @throws Exception
     */
    public static function __callStatic(string $name, array $arguments)
    {
        [$type, $base, $class] = static::parseName($name);
        if ("{$type}{$base}" !== $name) {
            throw new Exception("抱歉，实例 {$name} 不符合规则！");
        }
        if (class_exists($class)) {
            return new $class(static::getConfig());
        }

        throw new Exception("抱歉，接口模式无法实例 {$class} 对象！");
    }

    /**
     * 解析调用对象名称
     * @param $name
     * @return array
     */
    private static function parseName($name): array
    {
        if (strpos($name, 'WeMini') === 0) {
            [, $base] = explode('WeMini', $name);
            return ['WeMini', $base, "\\WeMini\\{$base}"];
        }
        return ['-', '-', $name];
    }

    /**
     * 获取小程序配置信息
     * @return array
     */
    public static function getConfig(): array
    {
        return ConfigService::getWeMiniConfig();
    }

    /**
     * 获取微信小程序授权手机号/不带区号
     * @param [type] $code
     * @return string
     * @throws Exception
     */
    public static function getPhoneNumber($code): ?string
    {
        try {
            $result = static::WeMiniCrypt()->getPhoneNumber($code);
            Log::info('微信手机号授权解密:' . json_encode($result));
            return $result['phone_info']['purePhoneNumber'];
        } catch (Exception $e) {
            throw new Exception('手机号获取失败');
        }
    }

    /**
     * 获取微信登录信息/session
     * @param [type] $code
     * @return array
     * @throws Exception
     */
    public static function getWeLoginSession($code): ?array
    {
        try {
            return static::WeMiniCrypt()->session($code);
        } catch (Exception $e) {
            throw new Exception('微信登录失败');
        }
    }

    /**
     * 微信加密数据解密
     * @param $iv
     * @param $sessionKey
     * @param $encryptedData
     * @return array|bool
     * @throws Exception
     */
    public static function decodeCrypt($iv, $sessionKey, $encryptedData)
    {
        try {
            return static::WeMiniCrypt()->decode($iv, $sessionKey, $encryptedData);
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 创建小程序链接
     * @param $data
     * @return mixed
     * @throws Exception
     */
    public static function createUrlLink($data)
    {
        try {
            return static::WeMiniScheme()->urlLink($data);
        } catch (Exception $e) {
            throw new Exception('创建失败');
        }
    }
}
